package com.tju.resource.business.tb_material;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.tju.resource.common.ServiceException;
import com.tju.resource.mapper.*;
import com.tju.resource.model.TbMaterial;
import com.tju.resource.model.TbMatlConsumables;
import com.tju.resource.model.TbRmMatl;
import com.tju.resource.business.tb_prod_plan.TbProdPlanService;
import com.tju.resource.result.Result;
import com.tju.resource.result.ResultEnum;
import com.tju.resource.result.ResultUtil;
import com.tju.resource.tool.tool.EmptyUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Map;

import static com.tju.resource.tool.tool.QuickQuery.*;

/**
 *
 */
@Service
public class TbMaterialServiceImpl implements TbMaterialService {

    @Autowired
    TbMaterialMapper mapper;
    @Autowired
    private TbProdPlanService pService;
    @Autowired
    private TbOrderMapper tbOrderMapper;
    @Autowired
    private TbRmMatlMapper tbRmMatlMapper;
    @Autowired
    private TbMatlConsumablesMapper tbMatlConsumablesMapper;
    @Autowired
    private TbConsumablesMapper tbConsumablesMapper;
    @Autowired
    private TbRawMatlMapper tbRawMatlMapper;

    @Override
    public Result<Object> getAll(Map<String, String> params) {
        try {
            Page<TbMaterial> page = new Page<>(Long.parseLong(params.get("page")), Long.parseLong(params.get("limit")));
            IPage<TbMaterial> iPage = mapper.getAll(page, params);
            List<TbMaterial> records = iPage.getRecords();
            for (TbMaterial record : records) {
                /*List<TbRmMatl> rmMatlList = record.getRmMatlList();
                for (TbRmMatl rmMatl : rmMatlList) {
                    int reMatlNumber = rmMatl.getRawMatl().getRmStoke() - rmMatl.getRmRadio(); //算出来库存够不够
                    Double rmWeight = rmMatl.getRawMatl().getRmWeight(); //单重
                    rmMatl.setNeedWeight(reMatlNumber < 0 ? 0 : reMatlNumber * rmWeight); //缺少重量
                    rmMatl.setLackPcs(Math.max(reMatlNumber, 0));    //缺少数量
                    rmMatl.setWeight(rmMatl.getRmRadio() * rmWeight);     //总重
                }
                record.setRmMatlList(rmMatlList);*/
            }
            return ResultUtil.success(ResultEnum.SUCCESS, records, iPage.getTotal());
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    @Override
    public Result<Object> byName(Map<String, String> params) {
        try {
            Page<TbMaterial> page = new Page<>(Long.parseLong(params.get("page")), Long.parseLong(params.get("limit")));
            IPage<TbMaterial> iPage = mapper.getAll(page, params);
            List<TbMaterial> records = iPage.getRecords();
            return ResultUtil.success(ResultEnum.SUCCESS, records, iPage.getTotal());
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 根据订单查询物料 模具
     *
     * @return
     */
    @Override
    public Result<Object> byOrderNumber(Map<String, String> params) {
        if (EmptyUtils.isNotEmpty(params.get("orderNumber"))) {
            Page<TbMaterial> page = new Page<>(Long.parseLong(params.get("page")), Long.parseLong(params.get("limit")));
            IPage<TbMaterial> iPage = mapper.byOrderNumber(page, params);
            List<TbMaterial> records = iPage.getRecords();
            for (TbMaterial record : records) {
                record.setRmMatlList(mapper.selectTbRmMatl(record.getId()));
            }
            return ResultUtil.success(ResultEnum.SUCCESS, iPage.getRecords(), iPage.getTotal());
        } else {
            return ResultUtil.error(ResultEnum.UNKONW_ERROR, "订单号不能为空!");
        }
    }

    @Override
    public Result<Object> byOrderMatlNumber(Map<String, String> pa) {
        try {
            if (EmptyUtils.isNotEmpty(pa.get("orderNumber")) && EmptyUtils.isNotEmpty(pa.get("two"))) {
                TbMaterial material = mapper.byOrderMatlNumber(pa);
                if (EmptyUtils.isNotEmpty(material)) {
                    return ResultUtil.success(ResultEnum.SUCCESS);
                } else {
                    return ResultUtil.error(ResultEnum.UNKONW_ERROR);
                }
            } else {
                return ResultUtil.error(ResultEnum.UNKONW_ERROR, "订单不能为空");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return ResultUtil.error(ResultEnum.UNKONW_ERROR);
    }

    /**
     * 添加物料下面的耗材
     *
     * @param material 物料下面的耗材
     * @return 结果
     */
    @Override
    @Transactional
    public Result<Object> addMatlConsumables(TbMaterial material) {
        if (EmptyUtils.isEmpty(material.getId())) return ResultUtil.error(ResultEnum.UNKONW_ERROR, "请输入物料id");
        if (EmptyUtils.isEmpty(mapper.selectById(material.getId())))
            return ResultUtil.error(ResultEnum.UNKONW_ERROR, "请选择存在的物料");
        insetMatlConsumables(material); //添加耗材
        return ResultUtil.success(ResultEnum.SUCCESS, "添加成功");
    }

    /**
     * 添加物料下面的原料
     *
     * @param material 物料下面的原料
     * @return 结果
     */
    @Override
    @Transactional
    public Result<Object> addMatlRmMatl(TbMaterial material) {
        if (EmptyUtils.isEmpty(material.getId())) return ResultUtil.error(ResultEnum.UNKONW_ERROR, "请输入物料id");
        if (EmptyUtils.isEmpty(mapper.selectById(material.getId())))
            return ResultUtil.error(ResultEnum.UNKONW_ERROR, "请选择存在的物料");
        insetRmMatl(material); //添加物料跟原材料关联表
        return ResultUtil.success(ResultEnum.SUCCESS, "添加成功");
    }

    @Override
    public TbMaterial byId(Long matlId) {
        return mapper.selectById(matlId);
    }

    @Override
    public TbMaterial byNo(String matlNumber) {
        return byOne(mapper, "matl_number", matlNumber);
    }

    @Override
    public TbMaterial byNa(String matlName) {
        return byOne(mapper, "matl_name", matlName);
    }

    @Override
    @Transactional
    public Result<Object> add(TbMaterial material) {
        TbMaterial matl = byNo(material.getMatlNumber());

        if (null == matl) {
            int insert = mapper.insert(material);

            if (insert > 0) {
                return ResultUtil.success(ResultEnum.SUCCESS, "新增物料完成!");
            }
        } else {
            return ResultUtil.error(ResultEnum.UNKONW_ERROR, "物料编号不可重复!");
        }

        return ResultUtil.error(ResultEnum.UNKONW_ERROR, "新增失败!");
    }

    @Override
    @Transactional
    public int upd(TbMaterial material) {
        return mapper.updateById(material);
    }

    @Override
    public int del(Long matlId) {
        if (EmptyUtils.isNotEmpty(tbOrderMapper.getListOrder(matlId)) || EmptyUtils.isNotEmpty(pService.getByMatlId(matlId))) {
            throw new ServiceException("物料被使用了不能删除！");
        }
        deleteTbRmMatl(matlId);//删除原材料
        return mapper.deleteById(matlId);
    }

    /**
     * 删除物料跟原材料关联表
     *
     * @param id 删除物料的id
     */
    private void deleteTbRmMatl(Long id) {
        QueryWrapper<TbRmMatl> qw = new QueryWrapper<>();
        qw.eq("matl_id", id);
        tbRmMatlMapper.selectList(qw).forEach(t -> tbRmMatlMapper.deleteById(t.getId())); //删除原材料
    }

    /**
     * 删除物料跟耗材关联表
     *
     * @param id 删除物料的id
     */
    private void deleteMatlConsumables(Long id,Integer consumablesType) {
        QueryWrapper<TbMatlConsumables> qw = new QueryWrapper<>();
        qw.eq("matl_id", id);
        qw.eq("type",consumablesType);
        tbMatlConsumablesMapper.selectList(qw).forEach(t -> tbMatlConsumablesMapper.deleteById(t.getId())); //删除原材料
    }

    /**
     * 添加原材料关联表
     *
     * @param material //物料
     */
    private void insetRmMatl(TbMaterial material) {
        if (EmptyUtils.isNotEmpty(material.getRmMatlList())) {
            deleteTbRmMatl(material.getId());//删除原材料
            for (TbRmMatl rmMatl : material.getRmMatlList()) {
                if (EmptyUtils.isNotEmpty(rmMatl.getRawMatl())) {  //判断不为空就用这个id
                    rmMatl.setId(rmMatl.getRawMatl().getId());
                }
                if (EmptyUtils.isEmpty(tbRawMatlMapper.selectById(rmMatl.getId())))
                    throw new ServiceException("请选择存在的原物料!");
                if (EmptyUtils.isEmpty(rmMatl.getRmRadio()) || rmMatl.getRmRadio() == 0)
                    throw new ServiceException("请选择原料的比数!");
                if(EmptyUtils.isEmpty(rmMatl.getRmFmWg())|| rmMatl.getRmFmWg() == 0){
                    throw new ServiceException("请选择原料的比重!");
                }
                rmMatl.setRmId(rmMatl.getId());//原料id
                rmMatl.setMatlId(material.getId()); //物料id
                rmMatl.setId(null);
                double rmLoss = EmptyUtils.isEmpty(rmMatl.getRmLoss()) ? 0 : rmMatl.getRmLoss() * 0.01;
                rmMatl.setRmLoss(rmLoss);
                rmMatl.setRmRadio((int) (rmMatl.getRmRadio() + Math.ceil(rmMatl.getRmRadio() * rmLoss))); //消耗数量
                if (tbRmMatlMapper.insert(rmMatl) == 0) throw new ServiceException("物料添加原料失败");
            }
        } else {
            throw new ServiceException("请选择物料所需的原材料");
        }
    }

    /**
     * 添加耗材关联表
     *
     * @param material //物料
     */
    private void insetMatlConsumables(TbMaterial material) {

        if (EmptyUtils.isNotEmpty(material.getMatlConsumablesList())) {  //判断耗材
            if(EmptyUtils.isEmpty(material.getConsumablesType()))
                throw new ServiceException("请输入耗材类型");
            deleteMatlConsumables(material.getId(),material.getConsumablesType());//删除耗材
            for (TbMatlConsumables MatlConsumables : material.getMatlConsumablesList()) {
                if (EmptyUtils.isNotEmpty(MatlConsumables.getConsumables())) {  //判断不为空就用这个id
                    MatlConsumables.setId(MatlConsumables.getConsumables().getId());
                }
                if (EmptyUtils.isEmpty(tbConsumablesMapper.selectById(MatlConsumables.getId())))  //判断是否存在耗材
                    throw new ServiceException("请选择存在的耗材");
                else if (EmptyUtils.isEmpty(MatlConsumables.getQty()) || MatlConsumables.getQty() == 0 ||EmptyUtils.isEmpty(MatlConsumables.getCount())||MatlConsumables.getQty()==0)  //判断消耗数量
                    throw new ServiceException("请输入耗材比数");
                MatlConsumables.setType(material.getConsumablesType());
                MatlConsumables.setConsumablesId(MatlConsumables.getId());//耗材id
                MatlConsumables.setMatlId(material.getId()); //物料id
                MatlConsumables.setId(null);
                if (tbMatlConsumablesMapper.insert(MatlConsumables) == 0) throw new ServiceException("物料添加耗材失败");
            }
        } else {
            throw new ServiceException("请选择物料所需的耗材");
        }
    }
}
